home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / WINDOWS / PROFFT.ARJ / MAINWIN.CPP < prev    next >
C/C++ Source or Header  |  1992-04-29  |  41KB  |  1,291 lines

  1. /****************************************************************************
  2.     MAINWIN.CPP        Denne filen inneholder (i denne rekkef°lgen):
  3. *****************************************************************************
  4. TMainWindow::TMainWindow(LPSTR ATitle) : TMDIFrame(ATitle, APP_NAME)
  5. TMainWindow::~TMainWindow()
  6. void TMainWindow::GetWindowClass(WNDCLASS& wc)
  7. LPSTR TMainWindow::GetClassName()
  8. void TMainWindow::CMFileOpen(TMessage&)
  9. void TMainWindow::CMFileSaveAs(TMessage&)
  10. void TMainWindow::CMEditCut(TMessage&)
  11. void TMainWindow::CMEditCopy(TMessage&)
  12. void TMainWindow::CMEditPaste(TMessage&)
  13. void TMainWindow::CMTransformFFT(TMessage&)
  14. void TMainWindow::CMTransformIFFT(TMessage&)
  15. void TMainWindow::CMTransformInvert(TMessage&)
  16. void TMainWindow::CMFilterLowpass(TMessage&)
  17. void TMainWindow::CMFilterHighpass(TMessage&)
  18. void TMainWindow::CMFilterBandpass(TMessage&)
  19. void TMainWindow::CMFilterBandstop(TMessage&)
  20. void TMainWindow::CMFilterBWLowpass(TMessage&)
  21. void TMainWindow::CMFilterBWHighpass(TMessage&)
  22. void TMainWindow::CMFilterFreehand(TMessage&)
  23. void TMainWindow::CMFilterOptions(TMessage&)
  24. void TMainWindow::CMHelpAbout(TMessage&)
  25. void TMainWindow::CMHelpIndex(TMessage&)
  26. BOOL TMainWindow::CheckForHelp(int CM_ID)
  27. BOOL TMainWindow::CanClose()
  28. void TMainWindow::ChangeRubber()
  29. HPALETTE TMainWindow::CreateGrayscalePalette()
  30. void TMainWindow::SetupWindow()
  31. PTWindowsObject TMainWindow::CreateChild(LPSTR FileName,
  32.                                                                 BITMAPINFO *bmpInfo, HANDLE hBitmap)
  33. PTWindowsObject TMainWindow::CreateComplexChild(LPSTR FileName,
  34.                                     HANDLE hComplexPict, BITMAPINFO *bmpInfo, HANDLE hBitmap)
  35. void TMainWindow::SetRubberSize(int iSize)
  36. int TMainWindow::GetRubberSize()
  37. BOOL TMainWindow::WMQueryNewPalette(TMessage&)
  38. void TMainWindow::WMIdle(TMessage& Msg)
  39. void TMainWindow::WMDrawClipboard(TMessage& Msg)
  40. void TMainWindow::WMChangeCBChain(TMessage& Msg)
  41. void TMainWindow::CreateClipboardChild()
  42. void TMainWindow::GetBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
  43. void TMainWindow::WriteBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
  44. BOOL TMainWindow::OpenDIB(int TheFile, LPSTR FileName)
  45. BOOL TMainWindow::LoadBitmapFile(LPSTR Name)
  46. BOOL TMainWindow::SaveBitmapFile(LPSTR Name)
  47.  
  48.  
  49. ****************************************************************************/
  50.  
  51. #include <owl.h>
  52. #include <filedial.h>
  53. #include <dir.h>
  54. #include <string.h>
  55.  
  56. #pragma hdrstop
  57.  
  58. #include "profftid.h" // Symbolske konstanter
  59. #include "profft.h"   // Klassedefinisjoner
  60. #include "prcomp.h"
  61.  
  62. TMainWindow::TMainWindow(LPSTR ATitle) : TMDIFrame(ATitle, APP_NAME)
  63. /****************************************************************************
  64. Setter opp en del standardparametre og klargj°r noen programressurser.
  65. Kaller ogsσ superklassen sin konstruktor.
  66.  
  67. LPSTR ATitle    Tittelen pσ hovedvinduet.
  68.  
  69. Kodet av:   MK
  70. Modifisert:    MK  01.04.92  La inn menyvalg i.h.t. kons.spek.
  71.                         MK  04.04.92  Flere menyvalg.
  72.                         MK    23.04.92    Flere menyvalg.
  73.                         MK  25.04.92  Clipboardfunksjoner.
  74.                         LW/MK 26.04.92 Flere menyvalg + fillagring.
  75. *****************************************************************************/
  76. {
  77.     prcomplex far *z;
  78.     int i;
  79.  
  80.     //  Setter hvilken meny som skal fσ oversikten over σpne vinduer.
  81.     ChildMenuPos = 4;
  82.  
  83.     //  Brukeren har hittil ikke trykket hjelp.
  84.     bHelp = FALSE;
  85.  
  86.     //  Default st°rrelse pσ viskelµret som brukes ved frihσndsfiltrering.
  87.     iRubberSize = 10;
  88.  
  89.     //  Det er ikke allokert noen brush til viskelµret ennσ.
  90.     hRubber = NULL;
  91.  
  92.     //  Cursoren til viskelµret er ikke laget ennσ
  93.     hcrRubber = NULL;
  94.  
  95.     //  Vis timeglasset mens vi lager tabellen.
  96.     hcrWait = LoadCursor(NULL, IDC_WAIT);
  97.  
  98.     //  Allokerer minne til tabellen som benyttes ved oppslag ved
  99.     //  konvertering av BYTE til et komplekst tall.
  100.     hByteToComplexTable = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 256*sizeof(prcomplex));
  101.  
  102.     //  Her fyller vi inn tallene i tabellen en gang for alle.
  103.     if (hByteToComplexTable!=NULL)
  104.     {
  105.         z = (prcomplex far *)GlobalLock(hByteToComplexTable);
  106.         for (i=0;i<=255;i++)
  107.         {
  108.             z[i].re = (real)i;
  109.             z[i].im = (real)0;
  110.         }
  111.         GlobalUnlock(hByteToComplexTable);
  112.     }
  113.     else
  114.         MessageBox(HWindow, "TMainWindow::TMainWindow hByteToRealTable==NULL", ERROR_CAPTION, MB_OK);
  115. };
  116.  
  117. TMainWindow::~TMainWindow()
  118. /****************************************************************************
  119. Rydder opp de ressursene som TMainWindow har allokert.
  120.  
  121. Kodet av:   MK
  122. Modifisert:    MK    23.04.92  Viskelµrressurser..
  123. *****************************************************************************/
  124. {
  125.     //  Sletter de ressursene som brukes i forbindelse med vσr spesielle
  126.     //  cursor ved frihσndsfiltrering. MERK! Disse allokeres ikke i
  127.     //    konstruktoren men i TMainWindow::SetupWindow
  128.     SelectObject(hdcBitmap, hbmOld);
  129.     DeleteDC(hdcBitmap);
  130.     DeleteObject(hbm);
  131.     GlobalUnlock(hmemAND);
  132.     GlobalUnlock(hmemXOR);
  133.     GlobalFree(hmemAND);
  134.     GlobalFree(hmemXOR);
  135.  
  136.     //  Kobler oss vekk fra Clipboardviewer kjeden
  137.     ChangeClipboardChain(HWindow, hwndNextViewer);
  138.  
  139.     //  Sletter grσtonepaletten. MERK! Denne allokeres i TMainWindow::SetupWindow
  140.     DeleteObject(hPal);
  141.  
  142.     //  Hvis vi fortsatt har en aktivt viskelµrcursor, slett dette
  143.     if (hcrRubber!=NULL)
  144.         DestroyCursor(hcrRubber);
  145.  
  146.     //  Slett viskelµrpennen
  147.     if (hRubber!=NULL)
  148.         DeleteObject(hRubber);
  149.  
  150.     //  Dealloker tabellen som konverterer BYTE til komplekse tall
  151.     if (hByteToComplexTable!=NULL)
  152.         GlobalFree(hByteToComplexTable);
  153.  
  154.     TMDIFrame::~TMDIFrame();
  155. }
  156.  
  157. void TMainWindow::GetWindowClass(WNDCLASS& wc)
  158. /****************************************************************************
  159. Henter vindusklassen og standardikon for vinduet.
  160.  
  161. Kodet av:   MK 28.04.92
  162. *****************************************************************************/
  163. {
  164.     TMDIFrame::GetWindowClass(wc);
  165.     wc.hIcon = LoadIcon(wc.hInstance, "COMPLEX");
  166. }
  167.  
  168. LPSTR TMainWindow::GetClassName()
  169. /****************************************************************************
  170. Returnerer vindusklassen.
  171.  
  172. Kodet av:   MK 28.04.92
  173. *****************************************************************************/
  174. {
  175.     return "PROfft:MainWindow";
  176. }
  177.  
  178. void TMainWindow::CMFileOpen(TMessage&)
  179. /****************************************************************************
  180. Kalles nσr brukeren velger Open fra menyen. Gir brukeren en filσpne
  181. dialogboks og fors°ker σ laste valgt fil hvis brukeren trykker OK
  182. button.
  183.  
  184. Kodet av:   MK    03.04.92
  185. *****************************************************************************/
  186. {
  187.     char TempName [MAXPATH];
  188.     char CaptionBuffer [MAXPATH+ 12 /*BSA_NAME*/ + 2 /*" "*/ + 1 /*'\0'*/ ];
  189.     HCURSOR hcrOld;
  190.  
  191.     //  Hvis brukeren ikke trykket hjelp
  192.     if (!CheckForHelp(CM_FILEOPEN))
  193.     {
  194.         //  Hvis brukeren velger fil og trykker OK sσ fors°k σ hent fil
  195.         if (GetApplication()->ExecDialog( new TPROfftFileDialog
  196.                 (this, SD_FILEOPEN, strcpy(TempName, "*.bmp"))) == IDOK )
  197.         {
  198.             hcrOld = SetCursor(hcrWait);
  199.             //  Hent fil
  200.             LoadBitmapFile(TempName);
  201.  
  202.             SetCursor(hcrOld);
  203.         }
  204.     }
  205. }
  206.  
  207. void TMainWindow::CMFileSaveAs(TMessage&)
  208. /****************************************************************************
  209. Kalles nσr brukeren velger Save fra menyen. Gir brukeren en fillagre
  210. dialogboks og fors°ker σ lagre valgt fil hvis brukeren trykker OK
  211. button.
  212.  
  213. Kodet av:   MK    26.04.92
  214. *****************************************************************************/
  215. {
  216.     char TempName [MAXPATH];
  217.     char CaptionBuffer [MAXPATH+ 12 /*BSA_NAME*/ + 2 /*" "*/ + 1 /*'\0'*/ ];
  218.     HCURSOR hcrOld;
  219.  
  220.     //  Hvis brukeren ikke trykket hjelp
  221.     if (!CheckForHelp(CM_FILESAVEAS))
  222.     {
  223.         //  Hvis brukeren gir et filnavn og trykker OK
  224.         if (GetApplication()->ExecDialog( new TPROfftFileDialog
  225.                 (this, SD_FILESAVE, strcpy(TempName, "*.bmp"))) == IDOK )
  226.         {
  227.             hcrOld = SetCursor(hcrWait);
  228.  
  229.             //  Fors°k σ lagre fil
  230.             SaveBitmapFile(TempName);
  231.  
  232.             SetCursor(hcrOld);
  233.         }
  234.     }
  235. }
  236.  
  237. void TMainWindow::CMEditCut(TMessage&)
  238. /****************************************************************************
  239. Kalles nσr brukeren velger Cut fra menyen. Denne kaller rutinen som
  240. kopierer bitmaprepresentasjonen av det aktive vinduet til clipboard og
  241. gir deretter objektet (vinduet) beskjed om σ fjerne seg selv.
  242.  
  243. Kodet av:   MK    26.04.92
  244. *****************************************************************************/
  245. {
  246.     //  Hvis brukeren ikke trykket hjelp
  247.     if (!CheckForHelp(CM_EDITCUT))
  248.     {
  249.         //  Hvis vi har et aktivt barnevindu..
  250.         if (ActiveChild!=NULL)
  251.         {
  252.             //  Kopier til clipboard
  253.             ((TGenericPicWindow *)ActiveChild)->EditCopy();
  254.  
  255.             //  Be vinduet fjerne seg selv
  256.             SendMessage(((TGenericPicWindow *)ActiveChild)->HWindow, WM_CLOSE, 0, 0L);
  257.         }
  258.     }
  259. }
  260.  
  261. void TMainWindow::CMEditCopy(TMessage&)
  262. /****************************************************************************
  263. Kalles nσr brukeren velger Edit fra menyen. Denne kaller rutinen som
  264. kopierer bitmaprepresentasjonen av det aktive vinduet til clipboard.
  265.  
  266. Kodet av:   MK    26.04.92
  267. *****************************************************************************/
  268. {
  269.     //  Hvis ikke hjelpemodus
  270.     if (!CheckForHelp(CM_EDITCOPY))
  271.     {
  272.         //  Hvis vi har et aktivt barnevindu..
  273.         if (ActiveChild!=NULL)
  274.             ((TGenericPicWindow *)ActiveChild)->EditCopy();
  275.     }
  276. }
  277.  
  278. void TMainWindow::CMEditPaste(TMessage&)
  279. /****************************************************************************
  280. Kalles nσr brukeren velger Paste fra menyen. Denne kaller rutinen som
  281. fors°ker σ lage et TPictureWindow objekt fra clipboard. OBS! Vi
  282. supporterer kun DIB (Device Independent Bitmap) fra clipboard..
  283.  
  284. Kodet av:   MK    26.04.92
  285. *****************************************************************************/
  286. {
  287.     //  Hvis ikke hjelpemodus..
  288.     if (!CheckForHelp(CM_EDITCOPY))
  289.     {
  290.         //  Lag TPictureWindow objekt fra clipboard
  291.         CreateClipboardChild();
  292.     }
  293. }
  294.  
  295. void TMainWindow::CMTransformFFT(TMessage&)
  296. /****************************************************************************
  297. Kalles nσr brukeren velger FFT fra menyen. Denne kaller rutinen som
  298. ber TPictureWindow om σ FFT seg selv.
  299.  
  300. Kodet av:   MK
  301. *****************************************************************************/
  302. {
  303.     //  Hvis ikke hjelpemodus
  304.     if (!CheckForHelp(CM_TRANSFFT))
  305.     {
  306.         //  Hvis vi har et aktivt barnevindu
  307.         if (ActiveChild!=NULL)
  308.             ((TPictureWindow *)ActiveChild)->PerformFFT();
  309.     }
  310. }
  311.  
  312. void TMainWindow::CMTransformIFFT(TMessage&)
  313. /****************************************************************************
  314. Kalles nσr brukeren velger IFFT fra menyen. Denne kaller rutinen som
  315. ber TComplexWindow om σ IFFT seg selv.
  316.  
  317. Kodet av:   MK
  318. *****************************************************************************/
  319. {
  320.     if (!CheckForHelp(CM_TRANSIFFT))
  321.     {
  322.         if (ActiveChild!=NULL)
  323.             ((TComplexWindow *)ActiveChild)->PerformIFFT();
  324.     }
  325. }
  326.  
  327. void TMainWindow::CMTransformInvert(TMessage&)
  328. /****************************************************************************
  329. Kalles nσr brukeren velger Invert fra menyen. Denne kaller rutinen som
  330. ber TPictureWindow om σ invertere seg selv.
  331.  
  332. Kodet av:   MK
  333. *****************************************************************************/
  334. {
  335.     HCURSOR hcrOld;
  336.  
  337.     if (!CheckForHelp(CM_TRANSINVERT))
  338.     {
  339.         if (ActiveChild!=NULL)
  340.         {
  341.             hcrOld = SetCursor(hcrWait);
  342.             ((TPictureWindow *)ActiveChild)->Invert();
  343.             SetCursor(hcrOld);
  344.         }
  345.     }
  346. }
  347.  
  348. /****************************************************************************
  349. CMFilter* rutinene under setter filtertype i det aktive TComplexWindow
  350. objektet og kaller deretter den aktuelle dialogboksen for det aktuelle
  351. filteret.
  352.  
  353. For lavpass og h°ypass filtrene (inkludert Butterworth) kalles
  354. ExecuteSmallDialog() som er den dialogboksen som lar deg velge en stk.
  355. radius.
  356.  
  357. For de andre kalles ExecuteLargeDialog() som lar deg velge to radiuser.
  358.  
  359. Ved valg av radiuser vil filtrene vise seg i det aktuelle
  360. TComplexWindow objektet.
  361.  
  362. Kodet av:   MK
  363. *****************************************************************************/
  364.  
  365. void TMainWindow::CMFilterLowpass(TMessage&)
  366. {
  367.     if (!CheckForHelp(CM_FILTERLOWPASS))
  368.     {
  369.         ((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERLOWPASS;
  370.         ((TComplexWindow *)ActiveChild)->ExecuteSmallDialog();
  371.     }
  372. }
  373.  
  374. void TMainWindow::CMFilterHighpass(TMessage&)
  375. {
  376.     if (!CheckForHelp(CM_FILTERHIGHPASS))
  377.     {
  378.         ((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERHIGHPASS;
  379.         ((TComplexWindow *)ActiveChild)->ExecuteSmallDialog();
  380.     }
  381. }
  382.  
  383. void TMainWindow::CMFilterBandpass(TMessage&)
  384. {
  385.     if (!CheckForHelp(CM_FILTERBANDPASS))
  386.     {
  387.         ((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERBANDPASS;
  388.         ((TComplexWindow *)ActiveChild)->ExecuteLargeDialog();
  389.     }
  390. }
  391.  
  392. void TMainWindow::CMFilterBandstop(TMessage&)
  393. {
  394.     if (!CheckForHelp(CM_FILTERBANDSTOP))
  395.     {
  396.         ((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERBANDSTOP;
  397.         ((TComplexWindow *)ActiveChild)->ExecuteLargeDialog();
  398.     }
  399. }
  400.  
  401. void TMainWindow::CMFilterBWLowpass(TMessage&)
  402. {
  403.     if (!CheckForHelp(CM_FILTERBWLOWPASS))
  404.     {
  405.         ((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERBWLOWPASS;
  406.         ((TComplexWindow *)ActiveChild)->ExecuteSmallDialog();
  407.     }
  408. }
  409.  
  410. void TMainWindow::CMFilterBWHighpass(TMessage&)
  411. {
  412.     if (!CheckForHelp(CM_FILTERBWHIGHPASS))
  413.     {
  414.         ((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERBWHIGHPASS;
  415.         ((TComplexWindow *)ActiveChild)->ExecuteSmallDialog();
  416.     }
  417. }
  418.  
  419. void TMainWindow::CMFilterFreehand(TMessage&)
  420. /****************************************************************************
  421. Kalles nσr brukeren velger Freehand fra menyen. Denne kaller rutinen som
  422. utf°rer frihσndsfilteret. Merk! Den starter ikke opp noen dialogboks som
  423. de andre filtrene, men utf°rer filtreringen direkte i bildet. Den
  424. forutsetter at brukeren allerede har tegnet inn med r°dt de omrσdene
  425. som °nskes fjernet.
  426.  
  427. Kodet av:   MK    23.04.92
  428. *****************************************************************************/
  429. {
  430.     if (!CheckForHelp(CM_FILTERFREEHAND))
  431.     {
  432.         ((TComplexWindow *)ActiveChild)->iFilterType = CM_FILTERFREEHAND;
  433.         ((TComplexWindow *)ActiveChild)->PrepareToExecuteFilter();
  434.     }
  435. }
  436.  
  437. void TMainWindow::CMFilterOptions(TMessage&)
  438. /****************************************************************************
  439. Kaller Options boksen. Denne lar deg forandre pσ standardverdiene
  440.  
  441. bShiftCenter  Hvorvidt det komplekse bildet skal sentreres
  442. iRubberSize   St°rrelsen pσ viskelµret
  443. iCircleRubber    Forteller hvorvidt viskelµret skal vµre rundt eller
  444.                             firkantet.
  445.  
  446. Kodet av:   MK    21.04.92
  447. Oppdatert:  MK  25.04.92  St°tte for forskjellige typer viskelµr
  448.                                                     (rundt eller firkantet).
  449. *****************************************************************************/
  450. {
  451.     TOptions *tdOptions;
  452.  
  453.     if (!CheckForHelp(CM_FILTEROPTIONS))
  454.     {
  455.         //  Instansier ny dialogboks
  456.         tdOptions = new TOptions(this, "RUBBER");
  457.         if (tdOptions==NULL)
  458.             MessageBox(HWindow, "TMainWindow::CMFilterOptions tdOptions==NULL",
  459.                     ERROR_CAPTION, MB_ERROR);
  460.         else
  461.             //  Vis dialogboksen og oppdater standardverdiene hvis brukeren
  462.             //  tastet OK.
  463.             GetApplication()->ExecDialog(tdOptions);
  464.     }
  465. }
  466.  
  467.  
  468. void TMainWindow::CMHelpAbout(TMessage&)
  469. /****************************************************************************
  470. Kaller opp About dialogboksen. Denne viser bare hvem som stσr bak
  471. dette systemet.
  472.  
  473. Kodet av:   MK    03.04.92
  474. *****************************************************************************/
  475. {
  476.     TDialog *tdAbout;
  477.  
  478.     tdAbout = new TDialog(this, "ABOUT");
  479.     if (tdAbout!=NULL)
  480.     {
  481.         GetApplication()->ExecDialog(tdAbout);
  482.     }
  483.     else
  484.         MessageBox(HWindow, "TMainWindow::CMHelpAbout tdAbout==NULL",
  485.                 ERROR_CAPTION, MB_ICONEXCLAMATION | MB_OK);
  486. }
  487.  
  488. void TMainWindow::CMHelpIndex(TMessage&)
  489. /****************************************************************************
  490. Kaller opp Windows hjelpesystemet og viser innholdsfortegnelsen.
  491.  
  492. Kodet av:   MK/RI    03.04.92
  493. *****************************************************************************/
  494. {
  495.     WinHelp(HWindow, HELP_FILE_NAME, HELP_INDEX, (DWORD) 0);
  496. }
  497.  
  498.  
  499. #pragma argsused
  500. BOOL TMainWindow::CheckForHelp(int CM_ID)
  501. /****************************************************************************
  502. Denne er implementert for σ st°tte context sensitive hjelp for meny-
  503. valgene. Forel°pig har ikke hjelpefilen context sensitive hjelp, sσ
  504. vi kaller bare opp indexen. Alle menyvalgene kaller denne for σ sjekke
  505. om brukeren faktisk °nsker hjelp.
  506.  
  507. Returnerer:  TRUE   Hvis brukeren °nsket hjelp (trykket shift-F1)
  508.                          FALSE  Ellers
  509.  
  510. Kodet av:   MK/RI    03.04.92
  511. *****************************************************************************/
  512. {
  513.     //  Hvis vi er i hjelpemodus
  514.     if (bHelp)
  515.     {
  516.         bHelp = FALSE;
  517.  
  518.         //  Kall opp hjelpesystemet
  519.         WinHelp(HWindow, HELP_FILE_NAME, HELP_INDEX, (DWORD) 0);
  520.  
  521.         //  Si ifra til kalleren om at det var hjelp som var °nsket.
  522.         return TRUE;
  523.     }
  524.     else
  525.         return FALSE;
  526. }
  527.  
  528. BOOL TMainWindow::CanClose()
  529. /****************************************************************************
  530. Denne sjekker om det finnes noen aktive vinduer. Hvis det gj°r det sσ
  531. advarer vi brukeren om at han b°r lagre f°r han slutter. Hvis brukeren
  532. trykker Cancel avsluttes ikke programmet allikevel.
  533.  
  534. Returnerer:        TRUE        Hvis det ikke finnes aktivt barnevinduet eller
  535.                                             hvis det finnes aktivt barnevindu og brukeren
  536.                                             trykker OK i advarselsboksen.
  537.                             FALSE   ellers.
  538. Kodet av:   MK    03.04.92
  539. *****************************************************************************/
  540.  
  541. {
  542.     int iMsgBox;
  543.  
  544.     iMsgBox=IDOK;
  545.  
  546.     //  Hvis det finnes noe aktivt barnevindu..
  547.     if (ActiveChild!=NULL)
  548.         iMsgBox=MessageBox(HWindow, "Any changes not saved will be lost.\nDo you really want to exit PROfft?",
  549.                 "PROfft - Warning", MB_OKCANCEL);
  550.  
  551.     return iMsgBox==IDOK?TRUE:FALSE;
  552. }
  553.  
  554.  
  555. void TMainWindow::ChangeRubber()
  556. /****************************************************************************
  557. Denne lager en cursor som skal vµre aktiv i TComplexWindow objektene.
  558. Cursoren blir laget ut i fra st°rrelse og form som er valgt i
  559. Options.
  560.  
  561. Kodet av:   MK    23.04.92
  562. *****************************************************************************/
  563. {
  564.     HPEN hpenB;
  565.  
  566.     hpenB = GetStockObject(BLACK_PEN);
  567.  
  568.     //  Oppretter AND og XOR mask for cursoren
  569.     SelectObject(hdcBitmap, hbrWhite);
  570.     PatBlt(hdcBitmap, 0, 0, cxCursor, cyCursor, PATCOPY);
  571.     SelectObject(hdcBitmap, hbrBlack);
  572.     SelectObject(hdcBitmap, hpenB);
  573.  
  574.     //  Tegner inn cursorformen
  575.     if (bCircleRubber)
  576.         Ellipse(hdcBitmap, 0, 0, iRubberSize, iRubberSize);
  577.     else
  578.         Rectangle(hdcBitmap, 0, 0, iRubberSize, iRubberSize);
  579.  
  580.     GetBitmapBits(hbm, (DWORD)cbSize, lpAND);
  581.  
  582.     SelectObject(hdcBitmap, hbrBlack);
  583.     PatBlt(hdcBitmap, 0, 0, cxCursor, cyCursor, PATCOPY);
  584.  
  585.     SelectObject(hdcBitmap, hbrWhite);
  586.     SelectObject(hdcBitmap, hpenB);
  587.     if (bCircleRubber)
  588.         Ellipse(hdcBitmap, 0, 0, iRubberSize, iRubberSize);
  589.     else
  590.         Rectangle(hdcBitmap, 0, 0, iRubberSize, iRubberSize);
  591.     GetBitmapBits(hbm, (DWORD)cbSize, lpXOR);
  592.  
  593.     //  Hvis vi har en gammel cursor, slett denne
  594.     if (hcrRubber!=NULL)
  595.         DestroyCursor(hcrRubber);
  596.  
  597.     //  Lag ny cursor
  598.     hcrRubber = CreateCursor(GetApplication()->hInstance,
  599.             iRubberSize/2, iRubberSize/2,
  600.             cxCursor, cyCursor,
  601.             lpAND, lpXOR);
  602. }
  603.  
  604.  
  605. HPALETTE TMainWindow::CreateGrayscalePalette()
  606. /****************************************************************************
  607. Lager en grσtonepalette som inneholder opptil 256 grσtoner.
  608.  
  609. Returnerer:        HPALETTE  En Handle til en slik grσtonepalette.
  610.  
  611. Kodet av:   MK    03.04.92
  612. *****************************************************************************/
  613. {
  614.     LOCALHANDLE hLocalMem;
  615.     LOGPALETTE *plp;
  616.     HPALETTE hPal;
  617.     int i, nGrayLevel;
  618.  
  619.     //  Alloker midlertidig arbeidsminne til paletten
  620.     hLocalMem = LocalAlloc (LMEM_MOVEABLE, sizeof(LOGPALETTE) + 256 *
  621.                                     sizeof(PALETTEENTRY));
  622.     if (hLocalMem==NULL)
  623.          MessageBox(HWindow, "TMainWindow::CreateGrayscalePalette LocalAlloc(Palette)==NULL",
  624.              ERROR_CAPTION, MB_ICONEXCLAMATION | MB_OK);
  625.     else
  626.     {
  627.         plp = (LOGPALETTE *) LocalLock(hLocalMem);
  628.  
  629.         //  Sett palette dataene
  630.         plp->palVersion = 0x300;
  631.         plp->palNumEntries = 256;
  632.  
  633.         //  Lager alle 256 grσtonene.
  634.         for (i=0;i<=255;i++)
  635.         {
  636.             nGrayLevel = i;
  637.             plp->palPalEntry[i].peRed = nGrayLevel;
  638.             plp->palPalEntry[i].peGreen = nGrayLevel;
  639.             plp->palPalEntry[i].peBlue = nGrayLevel;
  640.             plp->palPalEntry[i].peFlags = 0;
  641.         }
  642.  
  643.         //  Oppretter paletten som et Windowsobjekt.
  644.         hPal = CreatePalette(plp);
  645.  
  646.         //  Frigj°r midlertidig arbeidsomrσde
  647.         LocalUnlock(hLocalMem);
  648.         LocalFree(hLocalMem);
  649.         if (hPal==NULL)
  650.         {
  651.             MessageBox(HWindow, "CreateGrayScalePalette failed..", ERROR_CAPTION, MB_OK);
  652.             return NULL;
  653.         }
  654.         else
  655.             return hPal;
  656.     }
  657.     return NULL;
  658. }
  659.  
  660. void TMainWindow::SetupWindow()
  661. /****************************************************************************
  662. Denne ordner flere ting som har med hovedvinduet σ gj°re.
  663.  
  664. Den lager viskelµrpennen (r°d). Den setter alle menyvalgene slik de skal
  665. vµre nσr programmet starter (slik at man ikke kan velge f.eks. FFT uten
  666. σ ha noe aktivt bilde). Lager grσtonepaletten. Kobler vσr applikasjon
  667. til clipboardet som en "clipboard viewer". Allokerer minne til vσr
  668. viskelµrcursor. Setter standard viskelµrst°rrelse.
  669.  
  670. Selv om ting som paletten og viskelµret egentlig kunne h°re til hvert enkelt
  671. barnevindu, har vi valgt σ si at disse tilh°rer hovedvinduet og at
  672. alle barnevinduene har samme palette og viskelµr.
  673.  
  674. Kodet av:   MK
  675. *****************************************************************************/
  676. {
  677.     int i;
  678.     HMENU hMenu;
  679.     HCURSOR hcrOld;
  680.     BOOL bError;
  681.     HDC hdc;
  682.  
  683.     hMenu=GetMenu(HWindow);
  684.  
  685.     hRubber = CreatePen(PS_SOLID, iRubberSize, 0);
  686.  
  687.     //  Slσr av alle menyvalg som ikke skal kunne brukes f°r vi har
  688.     //  et vindusobjekt σ jobbe med.
  689.  
  690.     for (i=CM_TRANSFFT;i<=CM_TRANSINVERT;i++)
  691.         EnableMenuItem(hMenu, i, MF_GRAYED);
  692.     for (i=CM_FILTERLOWPASS;i<CM_FILTERFREEHAND;i++)
  693.         EnableMenuItem(hMenu, i, MF_GRAYED);
  694.     EnableMenuItem(hMenu, CM_FILTERFREEHAND, MF_GRAYED);
  695.     EnableMenuItem(hMenu, CM_EDITCOPY, MF_GRAYED);
  696.     EnableMenuItem(hMenu, CM_EDITCUT, MF_GRAYED);
  697.     EnableMenuItem(hMenu, CM_FILESAVEAS, MF_GRAYED);
  698.  
  699.     TMDIFrame::SetupWindow();
  700.  
  701.     hwndNextViewer = SetClipboardViewer(HWindow);
  702.  
  703.     EnableMenuItem(hMenu, CM_EDITPASTE, IsClipboardFormatAvailable(CF_DIB)?MF_ENABLED:MF_GRAYED);
  704.  
  705.     hPal = CreateGrayscalePalette();
  706.  
  707.     cxCursor = GetSystemMetrics(SM_CXCURSOR);
  708.     cyCursor = GetSystemMetrics(SM_CYCURSOR);
  709.  
  710.     hbm = CreateBitmap(cxCursor, cyCursor, 1, 1, NULL);
  711.     hdc = GetDC(HWindow);
  712.     hdcBitmap = CreateCompatibleDC(hdc);
  713.     ReleaseDC(HWindow, hdc);
  714.     hbmOld = SelectObject(hdcBitmap, hbm);
  715.     cbSize = (cxCursor/8)*cyCursor;
  716.     bError = FALSE;
  717.     hmemAND = GlobalAlloc(GMEM_MOVEABLE, (DWORD) cbSize);
  718.     if (hmemAND!=NULL)
  719.     {
  720.         lpAND = GlobalLock(hmemAND);
  721.         hmemXOR = GlobalAlloc(GMEM_MOVEABLE, (DWORD) cbSize);
  722.         if (hmemXOR!=NULL)
  723.         {
  724.             lpXOR=GlobalLock(hmemXOR);
  725.             hbrWhite = GetStockObject(WHITE_BRUSH);
  726.             hbrBlack = GetStockObject(BLACK_BRUSH);
  727.         }
  728.         else
  729.             bError = TRUE;
  730.     }
  731.     else
  732.         bError = TRUE;
  733.     if (bError)
  734.         MessageBox(HWindow, "Error allocating memory for rubber cursor..", ERROR_CAPTION, MB_ERROR);
  735.     SetRubberSize(iRubberSize);
  736. }
  737.  
  738. PTWindowsObject TMainWindow::CreateChild(LPSTR FileName,
  739.                                                                 BITMAPINFO *bmpInfo, HANDLE hBitmap)
  740. /****************************************************************************
  741. Oppretter et nytt TPictureWindow objekt med ferdige initialiserte data.
  742.  
  743. LPSTR FileName             Opphavet til objektet (filnavn eller clipboard).
  744. BITMAPINFO *bmpInfo     Ferdig initialisert struktur som inneholder bilde-
  745.                                          st°rrelse o.l.
  746. HANDLE hBitmap             Handle til ferdig allokert og initialisert bitmap.
  747.  
  748. Returnerer:  Peker til det aktuelle TPictureWindow objektet.
  749.  
  750. Kodet av:   MK
  751. *****************************************************************************/
  752. {
  753.     return GetApplication()->MakeWindow(
  754.         new TPictureWindow(this, FileName, bmpInfo, hBitmap));
  755. }
  756.  
  757. PTWindowsObject TMainWindow::CreateComplexChild(LPSTR FileName,
  758.                                     HANDLE hComplexPict, BITMAPINFO *bmpInfo, HANDLE hBitmap)
  759. /****************************************************************************
  760. Oppretter et nytt TComplexWindow objekt med ferdige initialiserte data.
  761.  
  762. LPSTR FileName             Opphavet til objektet (filnavn eller clipboard).
  763. HANDLE hComplexPict     Handle til ferdig allokert komplekst bilde.
  764. BITMAPINFO *bmpInfo     Ferdig initialisert struktur som inneholder bilde-
  765.                                          st°rrelse o.l.
  766. HANDLE hBitmap             Handle til ferdig allokert og initialisert bitmap.
  767.  
  768. Returnerer:  Peker til det aktuelle TComplexWindow objektet.
  769.  
  770. Kodet av:   MK
  771. *****************************************************************************/
  772. {
  773.     return GetApplication()->MakeWindow(
  774.         new TComplexWindow(this, FileName, hComplexPict,
  775.                         bmpInfo, hBitmap));
  776. }
  777.  
  778. void TMainWindow::SetRubberSize(int iSize)
  779. /****************************************************************************
  780. Forandrer pσ st°rrelsen til viskelµret som brukes ved frihσnds-
  781. filtrering. Lager ny viskelµrcursor.
  782.  
  783. int iSize        Den nye st°rrelsen pσ viskelµret.
  784.  
  785. Kodet av:   MK
  786. Oppdatert:    MK    23.04.92
  787. *****************************************************************************/
  788. {
  789.     //  Setter ny standardst°rrelse
  790.     iRubberSize = iSize;
  791.  
  792.     //  Forandrer pσ cursoren
  793.     ChangeRubber();
  794.  
  795.     //  Fjerner evt. gammel og lager ny viskelµrpenn.
  796.     if (hRubber!=NULL)
  797.         DeleteObject(hRubber);
  798.     hRubber = CreatePen(PS_SOLID, iRubberSize, 0);
  799. }
  800.  
  801. int TMainWindow::GetRubberSize()
  802. /****************************************************************************
  803. Returnerer st°rrelsen pσ viskelµret.
  804.  
  805. Kodet av:   MK
  806. *****************************************************************************/
  807. {
  808.     return iRubberSize;
  809. }
  810.  
  811. BOOL TMainWindow::WMQueryNewPalette(TMessage&)
  812. /****************************************************************************
  813. Denne mottar melding fra Windows om denne applikasjonen °nsker σ forandre
  814. pσ paletten. Det vil vi, sσ det gj°r vi!
  815.  
  816. Returnerer:        TRUE   Hvis vi forandret paletten.
  817.                             FALSE  Hvis ikke.
  818.  
  819. Kodet av:   MK    03.04.92
  820. *****************************************************************************/
  821. {
  822.     HDC hdc;
  823.  
  824.     hdc=GetDC(HWindow);
  825.     SelectPalette(hdc, hPal, FALSE);
  826.     if (RealizePalette(hdc)>0)
  827.     {
  828.         ReleaseDC(HWindow, hdc);
  829.         InvalidateRect(HWindow, NULL, TRUE);
  830.         return TRUE;
  831.     }
  832.     else
  833.     {
  834.         ReleaseDC(HWindow, hdc);
  835.         return FALSE;
  836.     }
  837. }
  838.  
  839. void TMainWindow::WMIdle(TMessage& Msg)
  840. /****************************************************************************
  841. Denne kalles nσr vi befinner oss i menyen uten σ foreta oss noe. Den skal
  842. passe pσ at hvis vi trykker shift F1 sσ settes hjelpeflagget for det
  843. aktuelle valget og denne kalles.
  844.  
  845. TMessage& Msg        Om vi er i menyen.
  846.  
  847. Kodet av:   MK
  848. *****************************************************************************/
  849. {
  850.     //  Hvis vi er i menyen og brukeren trykker shift F1
  851.     if ((Msg.WParam == MSGF_MENU) &&
  852.             (GetKeyState(VK_F1) & 0x8000))
  853.     {
  854.         //  Sett hjelpeflagget og lat som om brukeren trykket F1
  855.         //  for σ kalle den aktuelle rutinen. De aktuelle rutinene
  856.         //  sjekker sσ igjen om hjelpeflagget er satt og starter
  857.         //  hjelpen hvis det er tilfelle.
  858.         bHelp = TRUE;
  859.         PostMessage(HWindow, WM_KEYDOWN, VK_RETURN, 0L);
  860.     }
  861. }
  862.  
  863. void TMainWindow::WMDrawClipboard(TMessage& Msg)
  864. /****************************************************************************
  865. Denne mottar beskjeder fra Windows om innholdet av clipboard har forandret
  866. seg. Den sender ogsσ beskjeden videre til andre vinduer som er med i
  867. clipboardviewer kjeden.
  868.  
  869. TMessage& Msg        Inneholder de aktuelle parametre som sendes videre.
  870.  
  871. Kodet av:   MK    25.04.92
  872. *****************************************************************************/
  873. {
  874.     HMENU hMenu;
  875.  
  876.     //  Hvis flere er med i clipboardviewer kjeden, send beskjeden
  877.     //  videre.
  878.     if (hwndNextViewer)
  879.         SendMessage(hwndNextViewer, Msg.Message, Msg.WParam, Msg.LParam);
  880.  
  881.     //  Sjekk om det er kommet noen DIB i clipboard og muliggj°r
  882.     //  Paste i vσr meny hvis sσ er tilfelle.
  883.     hMenu=GetMenu(HWindow);
  884.     EnableMenuItem(hMenu, CM_EDITPASTE, IsClipboardFormatAvailable(CF_DIB)?MF_ENABLED:MF_GRAYED);
  885. }
  886.  
  887. void TMainWindow::WMChangeCBChain(TMessage& Msg)
  888. /****************************************************************************
  889. Mottar beskjed om at det er skjedd en forandring i clipboardviewer
  890. kjeden og oppdaterer den nye kjeden. Sender ogsσ beskjeden videre til
  891. andre clipboardviewers.
  892.  
  893. TMessage& Msg        Inneholder de aktuelle parametre som sendes videre.
  894.  
  895. Kodet av:   MK    25.04.92
  896. *****************************************************************************/
  897. {
  898.     if (Msg.WParam==hwndNextViewer)
  899.         hwndNextViewer=LOWORD(Msg.LParam);
  900.     else if (hwndNextViewer)
  901.                     SendMessage(hwndNextViewer, Msg.Message, Msg.WParam, Msg.LParam);
  902. }
  903.  
  904. void TMainWindow::CreateClipboardChild()
  905. /****************************************************************************
  906. Denne fors°ker σ opprette et TPictureWindow objekt fra DIBen som ligger
  907. i clipboard. Den sjekker om DIBen har 8 bits pr pixel, som er det eneste
  908. vi supporterer hittil.
  909.  
  910. Kodet av:   MK    25.04.92
  911. *****************************************************************************/
  912. {
  913.     HANDLE hCbdMem, hMem;
  914.     char huge *hpCbdMem, huge *hpMem;
  915.     WORD wSize;;
  916.     DWORD dwSize;
  917.     BITMAPINFO *lpNewBmpInfo;
  918.     int i, iY;
  919.     char acTemp[40];
  920.     long Count, lSize;
  921.     HCURSOR hcrOld;
  922.  
  923.     OpenClipboard(HWindow);
  924.  
  925.     //  Er DIBen i clipboard fortsatt tilgjengelig?
  926.     if (IsClipboardFormatAvailable(CF_DIB))
  927.     {
  928.         //  Fσ en handle til DIBen
  929.         hCbdMem = GetClipboardData(CF_DIB);
  930.         if (hCbdMem!=NULL)
  931.         {
  932.             hcrOld = SetCursor(hcrWait);
  933.             dwSize = GlobalSize(hCbdMem);
  934.             hpCbdMem = (char huge *)GlobalLock(hCbdMem);
  935.  
  936.             //  Regn ut st°rrelsen pσ BITMAPINFO strukturen (inkludert
  937.             //  paletten)
  938.             wSize = sizeof(BITMAPINFOHEADER) + ((1 << hpCbdMem[14])*sizeof(RGBQUAD));
  939.  
  940.             //  Alloker minne til denne
  941.             lpNewBmpInfo = (BITMAPINFO *)new char[wSize];
  942.  
  943.             //  Kopier strukturen fra clipboard
  944.             _fmemcpy(&lpNewBmpInfo[0], &hpCbdMem[0], wSize);
  945.  
  946.             //  Hvis 8 bits pr pixel
  947.             if (lpNewBmpInfo->bmiHeader.biBitCount==8)
  948.             {
  949.                 //  dwSize lik st°rrelsen pσ bildet.
  950.                 dwSize -= wSize;
  951.  
  952.                 //  Alloker minne til data fra clipboard
  953.                 hMem = GlobalAlloc(GMEM_PROFFTDATA, dwSize+MS_BUG);
  954.                 if (hMem!=NULL)
  955.                 {
  956.                     hpMem = (char huge *)GlobalLock(hMem);
  957.                     lSize = dwSize;
  958.  
  959.                     //  Sett hpCbdMem til σ peke pσ starten av bildedataene
  960.                     hpCbdMem=&hpCbdMem[wSize];
  961.  
  962.                     //  Kopier data byte for byte fra clipboard
  963.                     for (Count=0;Count<lSize;Count++)
  964.                         *hpMem++=*hpCbdMem++;
  965.  
  966.                     GlobalUnlock(hMem);
  967.  
  968.                     //  Opprett nytt TPictureWindow objekt..
  969.                     CreateChild("<Clipboard>", lpNewBmpInfo, hMem);
  970.                 }
  971.                 else
  972.                 {
  973.                     delete lpNewBmpInfo;
  974.                     GlobalFree(hMem);
  975.                     MessageBox(HWindow, "Paste: Error allocating memory for clipboard data",
  976.                             ERROR_CAPTION, MB_OK);
  977.                 }
  978.                 GlobalUnlock(hCbdMem);
  979.             }
  980.             else
  981.             {
  982.                 delete lpNewBmpInfo;
  983.                 MessageBox(HWindow, "Paste: Sorry, only 8 bits pr. pixel DIB format supported.",
  984.                         "PROfft - Warning", MB_ERROR);
  985.             }
  986.         }
  987.         CloseClipboard();
  988.         SetCursor(hcrOld);
  989.     }
  990. }
  991.  
  992. //  Denne brukes for σ lette arbeidet med σ aksessere minnet direkte
  993. //  i blokker st°rre enn 64K. Brukes av GetBitmapData()
  994. extern "C" {
  995. void FAR PASCAL __ahIncr();
  996. }
  997.  
  998. void TMainWindow::GetBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
  999. /****************************************************************************
  1000. Leser inn selve bilderσdataene fra en bitmap fil. Brukes av OpenDIB().
  1001.  
  1002. int TheFile                 Handle til filen.
  1003. HANDLE BitsHandle  Handle til minneblokken som skal motta dataene (mσ
  1004.                                      vµre allokert pσ forhσnd).
  1005. long BitsByteSize     Antall bytes som skal leses inn.
  1006.  
  1007. Kodet av:   MK    03.04.92
  1008. *****************************************************************************/
  1009. {
  1010.     long Count;
  1011.     long Start, ToAddr, Bits;
  1012.  
  1013.     Start = 0L;
  1014.     Bits = (long)GlobalLock(BitsHandle);
  1015.     Count = BitsByteSize - Start;
  1016.  
  1017.     //  Leser inn dataene fortl°pende
  1018.     while ( Count > 0 )
  1019.     {
  1020.         //  Regner ut adressen som skal motta dataene i minneblokken
  1021.         ToAddr = MAKELONG(LOWORD(Start),
  1022.                                             HIWORD(Bits) + (HIWORD(Start) * FP_OFF(__ahIncr)));
  1023.         if ( Count > 0x4000 )
  1024.             Count = 0x4000;
  1025.         _lread(TheFile, (LPSTR)ToAddr, (WORD)Count);
  1026.         Start = Start + Count;
  1027.         Count = BitsByteSize - Start;
  1028.     }
  1029.     GlobalUnlock(BitsHandle);
  1030. }
  1031.  
  1032. void TMainWindow::WriteBitmapData(int TheFile, HANDLE BitsHandle,long BitsByteSize)
  1033. /****************************************************************************
  1034. Skriver ut selve bilderσdataene til en bitmap fil. Brukes av CMFileSaveAs().
  1035.  
  1036. int TheFile                 Handle til filen.
  1037. HANDLE BitsHandle  Handle til minneblokken som skal motta dataene (mσ
  1038.                                      vµre allokert pσ forhσnd).
  1039. long BitsByteSize     Antall bytes som skal leses inn.
  1040.  
  1041. Kodet av:   MK    25.04.92
  1042. *****************************************************************************/
  1043. {
  1044.     long Count;
  1045.     long Start, FromAddr, Bits;
  1046.     BOOL bFailed;
  1047.  
  1048.     Start = 0L;
  1049.     Bits = (long)GlobalLock(BitsHandle);
  1050.     Count = BitsByteSize - Start;
  1051.     bFailed = FALSE;
  1052.     while (( Count > 0 ) && (!bFailed))
  1053.     {
  1054.         FromAddr = MAKELONG(LOWORD(Start),
  1055.                                             HIWORD(Bits) + (HIWORD(Start) * FP_OFF(__ahIncr)));
  1056.         if ( Count > 0x4000 )
  1057.             Count = 0x4000;
  1058.         if (_lwrite(TheFile, (LPSTR)FromAddr, (WORD)Count)<=0)
  1059.             bFailed = TRUE;
  1060.         Start = Start + Count;
  1061.         Count = BitsByteSize - Start;
  1062.     }
  1063.     if (bFailed)
  1064.         MessageBox(HWindow, "Save: Write to disk failed (disk full?).", ERROR_CAPTION, MB_OK);
  1065.     GlobalUnlock(BitsHandle);
  1066. }
  1067.  
  1068. BOOL TMainWindow::OpenDIB(int TheFile, LPSTR FileName)
  1069. /****************************************************************************
  1070. Fors°ker σ laste inn en Windows DIB fil.
  1071.  
  1072. int TheFile                 Handle til filen.
  1073. LPSTR    FileName         Filnavnet som skal leses inn.
  1074.  
  1075. Returnerer:        TRUE   Hvis formatet er kjent og kan leses inn.
  1076.                             FALSE  ellers.
  1077.  
  1078. Kodet av:   MK    03.04.92
  1079. *****************************************************************************/
  1080. {
  1081.         WORD bitCount;
  1082.         WORD size;
  1083.         long longWidth;
  1084.         HDC DCHandle;
  1085.         LPSTR BitsPtr;
  1086.         BITMAPINFO *BitmapInfo;
  1087.         HANDLE BitsHandle , NewBitmapHandle;
  1088.         DWORD NewPixelWidth , NewPixelHeight;
  1089.         BOOL retval;
  1090.  
  1091.     retval= TRUE;
  1092.     if (_llseek(TheFile, 28, 0)!=-1)
  1093.     {
  1094.         if (_lread(TheFile, (LPSTR)&bitCount, sizeof(bitCount))<(WORD)-1)
  1095.         {
  1096.             //  Hvis det er 8 bits pr pixel som er det formatet vi supporterer.
  1097.             if ( bitCount == 8 )
  1098.             {
  1099.                 //  Allokerer plass til en ny bildestruktur
  1100.                 size = sizeof(BITMAPINFOHEADER) + ((1 << bitCount) * sizeof(RGBQUAD));
  1101.                 BitmapInfo = (BITMAPINFO *)new char[size];
  1102.  
  1103.                 //  Leser dataene fra fil inn i den nye strukturen
  1104.                 _llseek(TheFile, sizeof(BITMAPFILEHEADER), 0);
  1105.                 _lread(TheFile, (LPSTR)BitmapInfo, size);
  1106.                 NewPixelWidth = BitmapInfo->bmiHeader.biWidth;
  1107.                 NewPixelHeight = BitmapInfo->bmiHeader.biHeight;
  1108.  
  1109.                 //  Regner ut bytes pr line.
  1110.                 longWidth = (((NewPixelWidth * bitCount) + 31)/32) * 4;
  1111.  
  1112.                 //  Regner ut bildest°rrelsen.
  1113.                 BitmapInfo->bmiHeader.biSizeImage = longWidth * NewPixelHeight;
  1114.  
  1115.                 //  Rydder opp i minnet f°r vi fors°ker σ allokere minne til et
  1116.                 //  nytt bitmap bilde.
  1117.                 GlobalCompact(-1);
  1118.  
  1119.                 //  Allokerer minne til et nytt bilde.
  1120.                 BitsHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
  1121.                         BitmapInfo->bmiHeader.biSizeImage+MS_BUG);
  1122.                 if (BitsHandle!=NULL)
  1123.                 {
  1124.                     //  Leser inn bildedataene.
  1125.                     GetBitmapData(TheFile, BitsHandle, BitmapInfo->bmiHeader.biSizeImage);
  1126.                         CreateChild(FileName, BitmapInfo, BitsHandle);
  1127.                 }
  1128.                 else
  1129.                 {
  1130.                     MessageBox(HWindow, "Open: Out of memory", ERROR_CAPTION,
  1131.                             MB_ERROR);
  1132.                     retval = FALSE;
  1133.                 }
  1134.             }
  1135.             else
  1136.             {
  1137.                 MessageBox(HWindow, "Open: Only 8 bits pr. pixel DIB format supported", ERROR_CAPTION,
  1138.                         MB_ERROR);
  1139.                 retval = FALSE;
  1140.             }
  1141.         }
  1142.         else
  1143.         {
  1144.             MessageBox(HWindow, "Open: Error reading file", ERROR_CAPTION,
  1145.                     MB_ERROR);
  1146.             retval = FALSE;
  1147.         }
  1148.     }
  1149.     else
  1150.     {
  1151.         MessageBox(HWindow, "Open: Error reading file", ERROR_CAPTION,
  1152.                 MB_ERROR);
  1153.         retval = FALSE;
  1154.     }
  1155.     return retval;
  1156. }
  1157.  
  1158. BOOL TMainWindow::LoadBitmapFile(LPSTR Name)
  1159. /****************************************************************************
  1160. Fors°ker σ laste inn en Windows DIB fil. Tester om filen er en Window
  1161. DI bitmap og fors°ker σ laste den hvis sσ er tilfelle.
  1162.  
  1163. LPSTR    FileName         Filnavnet som skal leses inn.
  1164.  
  1165. Returnerer:        TRUE   Hvis formatet er kjent og kan leses inn.
  1166.                             FALSE  ellers.
  1167.  
  1168. Kodet av:   MK    03.04.92
  1169. *****************************************************************************/
  1170. {
  1171.         int TheFile;
  1172.         long TestWin30Bitmap;
  1173.         char ErrorMsg[50] = "";
  1174.         BOOL retval;
  1175.  
  1176.     TheFile = _lopen(Name, OF_READ);
  1177.     if ( TheFile != -1 )
  1178.     {
  1179.         _llseek(TheFile, 14, 0);
  1180.         _lread(TheFile, (LPSTR)&TestWin30Bitmap, sizeof(TestWin30Bitmap));
  1181.         if ( TestWin30Bitmap == 40 )
  1182.             if ( OpenDIB(TheFile, Name) )
  1183. //                AdjustScroller();
  1184.                 ;
  1185.             else
  1186.                 strcpy(ErrorMsg,
  1187.                                         "Open: Unable to create Windows 3.0 bitmap from file");
  1188.         else
  1189.             strcpy(ErrorMsg, "Open: Not a Windows 3.0 bitmap file");
  1190.         _lclose(TheFile);
  1191.     }
  1192.     else
  1193.         strcpy(ErrorMsg, "Open: Cannot open bitmap file");
  1194.     if ( ErrorMsg[0] == '\0' )
  1195.         retval= TRUE;
  1196.     else
  1197.     {
  1198.         MessageBox(HWindow, ErrorMsg, ERROR_CAPTION, MB_ERROR);
  1199.         retval= FALSE;
  1200.     }
  1201.     return retval;
  1202. }
  1203.  
  1204. BOOL TMainWindow::SaveBitmapFile(LPSTR Name)
  1205. /****************************************************************************
  1206. Fors°ker σ lagre bitmapbildet i det aktive vinduet til en fil.
  1207.  
  1208. LPSTR Name     Filnavnet som det skal lagres til.
  1209.  
  1210. Returnerer:        TRUE   Hvis lagringen gikk ok.
  1211.                             FALSE  ellers.
  1212.  
  1213. Kodet av:   MK    03.04.92
  1214. *****************************************************************************/
  1215. {
  1216.         int TheFile, iBytesPrLine;
  1217.         long TestWin30Bitmap, lSize;
  1218.         char ErrorMsg[120] = "%s already exists.\nDo you wish to replace this file?";
  1219.         char Temp[120];
  1220.         BITMAPFILEHEADER bmpHeader;
  1221.         int iMsgBox, iWritten;
  1222.         BOOL retval, bFailed;
  1223.         TGenericPicWindow *ptActive;
  1224.         HCURSOR hcrOld;
  1225.  
  1226.     TheFile = _lopen(Name, OF_READWRITE);
  1227.     iMsgBox = IDOK;
  1228.     retval = TRUE;
  1229.     bFailed = FALSE;
  1230.  
  1231.     //  Tester om filen finnes fra f°r.
  1232.     if (TheFile != -1)
  1233.     {
  1234.         wsprintf(Temp, ErrorMsg, Name);
  1235.         iMsgBox = MessageBox(HWindow, Temp, "PROfft - Warning", MB_OKCANCEL);
  1236.     }
  1237.     else
  1238.     //  Hvis ikke, opprett den
  1239.     {
  1240.         TheFile = _lcreat(Name, 0);
  1241.         if (TheFile == -1)
  1242.         {
  1243.             MessageBox(HWindow, "Save: Could not create output file", ERROR_CAPTION, MB_OK);
  1244.             retval = FALSE;
  1245.         }
  1246.     }
  1247.     //  Hvis filen ikke fantes, eller den fantes og brukeren °nsket σ
  1248.     //  overskrive den.
  1249.     if (iMsgBox==IDOK)
  1250.     {
  1251.         hcrOld = SetCursor(hcrWait);
  1252.  
  1253.         //  Fyll ut BITMAPFILEHEADER og BITMAPINFO strukturene
  1254.         ptActive = ((TGenericPicWindow *)ActiveChild);
  1255.         lSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
  1256.                 +(1 << ptActive->bmpInfo->bmiHeader.biBitCount)
  1257.                 *sizeof(RGBQUAD);
  1258.         lstrcpy((LPSTR)&bmpHeader, "BM");
  1259.         iBytesPrLine = (((ptActive->bmpInfo->bmiHeader.biWidth
  1260.                 *ptActive->bmpInfo->bmiHeader.biBitCount) + 31) / 32) * 4;
  1261.         bmpHeader.bfSize=lSize+(((DWORD)iBytesPrLine
  1262.                 *(DWORD)ptActive->bmpInfo->bmiHeader.biHeight));
  1263.         bmpHeader.bfReserved1=0;
  1264.         bmpHeader.bfReserved2=0;
  1265.  
  1266.         //  Skriv filheaderen til disk, sjekk for feil
  1267.         if (_lwrite(TheFile, (LPSTR) &bmpHeader, sizeof(BITMAPFILEHEADER))<=0)
  1268.             bFailed=TRUE;
  1269.  
  1270.         //  Skriv bildestrukturen til disk, sjekk for feil
  1271.         if (_lwrite(TheFile, (LPSTR) ptActive->bmpInfo, sizeof(BITMAPINFOHEADER)
  1272.                 +(1 << ptActive->bmpInfo->bmiHeader.biBitCount)
  1273.                 *sizeof(RGBQUAD))<=0)
  1274.             bFailed=TRUE;
  1275.  
  1276.         //  Hvis skrivingen over gikk bra, lagre selve bildet.
  1277.         if (!bFailed)
  1278.             //  Skriv bildet til disk.
  1279.             WriteBitmapData(TheFile, ptActive->hBitmap,
  1280.                     ptActive->bmpInfo->bmiHeader.biSizeImage);
  1281.         _lclose(TheFile);
  1282.         SetCursor(hcrOld);
  1283.     }
  1284.     if (bFailed)
  1285.     {
  1286.         MessageBox(HWindow, "Save: Write to disk failed", ERROR_CAPTION, MB_OK);
  1287.         retval = FALSE;
  1288.     }
  1289.     return retval;
  1290. }
  1291.